package com.crm.base;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.crm.utils.ConvertHandler;
import com.github.pagehelper.Page;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;

@Data
@ApiModel(value = "API数据消息体", description = "API数据统一对象")
@Builder
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor
public class ApiResponse<T> {

    @ApiModelProperty(value = "总条目数", required = true)
    private int total = 0;

    @ApiModelProperty(value = "数据列表", required = true)
    private List<T> rows = Collections.emptyList();

    @ApiModelProperty(value = "状态码", required = true)
    private int code = 200;

    @ApiModelProperty(value = "消息", required = true)
    private String msg = "操作成功";

    @ApiModelProperty(value = "其他参数", required = true)
    private Map<String, Object> params;

    public static <T> ApiResponse<T> getInstance() {
        return ApiResponse.<T>builder().build();
    }

    public static <T> ApiResponse<T> of(List<T> rows, int total, int code, String msg, Map<String, Object> params) {
        return ApiResponse.<T>builder()
                .rows(rows)
                .total(total)
                .code(code)
                .msg(msg)
                .params(params)
                .build();
    }

    public static <T> ApiResponse<T> of(Page<T> page) {
        return ApiResponse.<T>builder()
                .rows(page.getResult())
                .total((int) page.getTotal())
                .code(200)
                .msg("操作成功")
                .build();
    }

    public static <O, T> ApiResponse<T> of(Page<O> page, Class<T> clazz, ConvertHandler<O, T> convertHandler) {
        List<T> convertedRows = copyToList(page.getResult(), clazz, convertHandler);
        return ApiResponse.<T>builder()
                .rows(convertedRows)
                .total((int) page.getTotal())
                .code(200)
                .msg("操作成功")
                .build();
    }

    public static <O, T> ApiResponse<T> of(List<O> originRows, Class<T> clazz, ConvertHandler<O, T> convertHandler) {
        List<T> convertedRows = copyToList(originRows, clazz, convertHandler);
        return ApiResponse.<T>builder()
                .rows(convertedRows)
                .total(originRows.size())
                .code(200)
                .msg("操作成功")
                .build();
    }

    private static <T, O> List<T> copyToList(List<O> content, Class<T> clazz, ConvertHandler<O, T> convertHandler) {
        List<T> targetList = BeanUtil.copyToList(content, clazz);
        if (CollUtil.isNotEmpty(targetList) && ObjectUtil.isNotEmpty(convertHandler)) {
            for (int i = 0; i < content.size(); i++) {
                convertHandler.map(content.get(i), targetList.get(i));
            }
        }
        return targetList;
    }
}
